class FastMath {

	public function new() {
	}

	public function sin1( f : Float ) : Float {
		// clamp to [-PI,PI]
		f = untyped __int__(f * 683565275.57643158978229477811035) / 683565275.57643158978229477811035; // 2^31/PI
		// first step
		var sin = f * 1.2732395447351626861510701069801 /* 4/PI */ - 0.40528473456935108577551785283891 /* -4/(pi*pi) */ * f * ((f < 0)?-f:f);
		// add approx
		if( sin < 0 )
			return .225 * (sin * -sin - sin) + sin;
		return .225 * (sin * sin - sin) + sin;
	}

	public inline function isin( angle : Float ) : Float {
		var f = Std.int(angle * 683565275.57643158978229477811035) >> 16;
		var sin = (f - ((f * ((f < 0)?-f:f)) >> 15)) * 41721;
		var ssin = sin >> 15;
		return (((ssin * (sin < 0?-ssin:ssin)) >> 9) * 467 + sin) / 441009855.21060102566599663103894;
	}

	public inline function icos( angle : Float ) : Float {
		var f = (Std.int(angle * 683565275.57643158978229477811035) + 1073741824) >> 16;
		var sin = (f - ((f * ((f < 0)?-f:f)) >> 15)) * 41721;
		var ssin = sin >> 15;
		return (((ssin * (sin < 0?-ssin:ssin)) >> 9) * 467 + sin) / 441009855.21060102566599663103894;
	}

	public function sin(angle) {
		return isin(angle);
	}

	public function cos(angle) {
		return icos(angle);
	}

	#if (flash10 && !as3)
	public function setupInvSqrt() {
		var b = new flash.utils.ByteArray();
		b.length = flash.system.ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH;
		flash.Memory.select(b);
	}

	public function invSqrt( x : Float ) : Float {
		var half = 0.5 * x;
		flash.Memory.setFloat(0,x);
		flash.Memory.setI32(0,0x5f3759df - (flash.Memory.getI32(0)>>1));
		x = flash.Memory.getFloat(0);
		return x * (1.5 - half*x*x);
	}
	#end

}